package cn.kk.utils;

import cn.hutool.core.date.DateUtil;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Calendar;
import java.util.Date;

/**
 * @author kinoko
 */
public class DateUtils extends DateUtil {
    public static String DATE_FORMAT = "yyyy-MM-dd";

    public static String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";

    //2019年07月09日
    public static String DATE_FORMAT_CHINESE = "yyyy年MM月dd日";
    //2019年07月09日 14:00:32
    public static String DATE_TIME_FORMAT_CHINESE = "yyyy年MM月dd日 HH:mm:ss";


    /**
     * 获取日期的DAY值
     * @param date 输入日期
     * @return 天数
     */
    public static int getDayOfDate(Date date) {
        return toLocalDateTime(date).getDayOfMonth();
    }

    /**
     * 获取日期的MONTH值
     * @param date 输入日期
     * @return  月份
     */
    public static int getMonthOfDate(Date date) {
        return toLocalDateTime(date).getMonthValue();
    }

    /**
     * 获取日期的YEAR值
     * @param date 输入日期
     * @return 年份
     */
    public static int getYearOfDate(Date date) {
        return toLocalDateTime(date).getYear();
    }

    /**
     * 获取星期几
     * @param date 输入日期
     * @return 星期
     */
    public static int getWeekOfDate(Date date) {
        return toLocalDateTime(date).getDayOfWeek().getValue();
    }

    /**
     * 获取输入日期的当月第一天
     * @param date 输入日期
     * @return 第一天日期
     */
    public static Date getFirstDayOfMonth(Date date) {
        return toDate(toLocalDateTime(date).withDayOfMonth(1));
    }

    /**
     * 判断是否是闰年
     * @param date 输入日期
     * @return 是true 否false
     */
    public static boolean isLeapYear(Date date) {
        LocalDateTime localDateTime = toLocalDateTime(date);
        int year = localDateTime.getYear();
        return year % 4 == 0 && year % 100 != 0 | year % 400 == 0;
    }

    /**
     * date转换localDateTime
     * @param date  date对象
     * @return  localDateTime对象
     */
    public static LocalDateTime toLocalDateTime(Date date) {
        return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
    }

    /**
     * date转换localDateTime
     * @param localDateTime  localDateTime对象
     * @return  date对象
     */
    public static Date toDate(LocalDateTime localDateTime) {
        return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * 根据整型数表示的年月日，生成日期类型格式
     * @param year  年
     * @param month 月
     * @param day   日
     * @return 日期
     */
    public static Date toDate(int year, int month, int day) {
        return toDate(LocalDate.of(year, month, day).atStartOfDay());
    }

    /**
     * 计算年龄
     * @param birthday 生日日期
     * @param calcDate 要计算的日期点
     * @return 年龄
     */
    public static int calcAge(Date birthday, Date calcDate) {

        int cYear = DateUtils.getYearOfDate(calcDate);
        int cMonth = DateUtils.getMonthOfDate(calcDate);
        int cDay = DateUtils.getDayOfDate(calcDate);
        int bYear = DateUtils.getYearOfDate(birthday);
        int bMonth = DateUtils.getMonthOfDate(birthday);
        int bDay = DateUtils.getDayOfDate(birthday);

        if (cMonth > bMonth || (cMonth == bMonth && cDay > bDay)) {
            return cYear - bYear;
        } else {
            return cYear - 1 - bYear;
        }
    }

    /**
     * 从身份证中获取出生日期
     * @param idCard 身份证号码
     * @return 出生日期
     */
    public static String getBirthDayFromIDCard(String idCard) {
        Calendar cd = Calendar.getInstance();
        if (idCard.length() == 15) {
            cd.set(Calendar.YEAR, Integer.parseInt("19" + idCard.substring(6, 8)));
            cd.set(Calendar.MONTH, Integer.parseInt(idCard.substring(8, 10)) - 1);
            cd.set(Calendar.DAY_OF_MONTH, Integer.parseInt(idCard.substring(10, 12)));
        } else if (idCard.length() == 18) {
            cd.set(Calendar.YEAR, Integer.parseInt(idCard.substring(6, 10)));
            cd.set(Calendar.MONTH, Integer.parseInt(idCard.substring(10, 12)) - 1);
            cd.set(Calendar.DAY_OF_MONTH, Integer.parseInt(idCard.substring(12, 14)));
        }
        return format(cd.getTime(), DateUtils.DATE_FORMAT);
    }

    /**
     * 在输入日期上增加（+）或减去（-）天数
     * @param date 输入日期
     * @param iday 要增加或减少的天数
     */
    public static Date addDay(Date date, int iday) {
        Calendar cd = Calendar.getInstance();

        cd.setTime(date);

        cd.add(Calendar.DAY_OF_MONTH, iday);

        return cd.getTime();
    }

    /**
     * 在输入日期上增加（+）或减去（-）月份
     * @param date   输入日期
     * @param imonth 要增加或减少的月分数
     */
    public static Date addMonth(Date date, int imonth) {
        Calendar cd = Calendar.getInstance();

        cd.setTime(date);

        cd.add(Calendar.MONTH, imonth);

        return cd.getTime();
    }

}